<?php
declare (strict_types=1);

// +----------------------------------------------------------------------
// | SCApi
// +----------------------------------------------------------------------
// | 版权所有 2021~2022 贾二小 [ http://www.ipsoul.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://www.ipsoul.com
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// | 免费声明 ( http://doc.ipsoul.com/disclaimer )
// +----------------------------------------------------------------------
// | gitee 代码仓库：https://gitee.com/jiaerxiao/scapi
// | github 代码仓库：https://github.com/jiaerxiao/scapi
// +----------------------------------------------------------------------

namespace app\system\service;

use app\common\service\BaseService;
use app\system\enum\MenuMetaEnum;
use app\system\facade\MenuApiFacade;
use app\system\facade\MenuMetaFacade;
use think\App;

class MenuService extends BaseService
{
    /**
     * 初始化
     * @param App $app
     */
    public function __construct(App $app)
    {
        parent::__construct($app, '菜单管理', 'menu');
    }

    /**
     * 获取我的菜单
     * @author 贾二小
     * @since 2021/11/11
     */
    public function myList(): array
    {
        if ($this->userData['userName'] == 'admin') {
            //超级管理员不验证权限
            $menuList = $this->list()->order('sort')->toArray();
        } else {
            $sql = "SELECT m.*FROM sys_menu m WHERE m.is_delete=0 AND m.id IN (SELECT DISTINCT rm.menu_id FROM sys_role_menu rm INNER JOIN sys_role r ON r.id=rm.role_id AND r.is_delete=0 INNER JOIN sys_user_role ur ON ur.role_id=r.id AND ur.user_id=?) ORDER BY m.sort";
            $menuList = self::query($sql, [$this->userData['id']]);
        }
        //没有菜单则返回空
        if (empty($menuList)) {
            return [];
        }
        $menuIds = array_column($menuList, 'id');
        $menuMetaList = MenuMetaFacade::list([['menuId', 'in', $menuIds]]);
        $data = array_map(function ($item) use ($menuMetaList) {
            foreach ($menuMetaList as $vo) {
                if ($item['id'] == $vo['menuId']) {
                    $vo['type'] = MenuMetaEnum::TYPE_DATA[$vo['type']];
                    $item['meta'] = $vo;
                }
            }
            return $item;
        }, $menuList);
        return get_tree($data, 0);
    }

    /**
     * 表格数据
     * @author 贾二小
     * @since 2021/11/20
     */
    public function tableList(): array
    {
        //获取菜单列表
        $map = [];
        $menuList = $this->list($map)->order('sort');
        //没有菜单则返回空
        if ($menuList->isEmpty()) {
            return [];
        }
        $menuIds = $menuList->column('id');
        $menuMetaList = MenuMetaFacade::list([['menuId', 'in', $menuIds]]);
        $menuApiList = MenuApiFacade::list([['menuId', 'in', $menuIds]]);
        $data = array_map(function ($item) use ($menuMetaList, $menuApiList) {
            foreach ($menuMetaList as $vo) {
                if ($item['id'] == $vo['menuId']) {
                    $item['meta'] = $vo;
                }
            }
            $item['apiList'] = [];
            foreach ($menuApiList as $vo) {
                if ($item['id'] == $vo['menuId']) {
                    $item['apiList'][] = $vo;
                }
            }
            return $item;
        }, $menuList->toArray());
        return get_tree($data, 0);
    }

    /**
     * 菜单保存/编辑
     * @author 贾二小
     * @since 2021/12/20
     */
    public function saving(array $paramData): array
    {
        $this->transaction(function () use (&$paramData) {
            $metaData = $paramData['meta'];
            $apiList = $paramData['apiList'];
            unset($paramData['meta'], $paramData['apiList']);
            if (isset($paramData['id']) && !empty($paramData['id']) && $paramData['id'] > 0) {
                //更新菜单
                $this->updateById($paramData['id'], $paramData);
                //更新Meta
                MenuMetaFacade::updateById($metaData['id'], $metaData);
                //更新Api
                $menu_id = $paramData['id'];
                $insertApiList = [];
                array_map(function ($item) use (&$insertApiList, $menu_id) {
                    if (isset($item['id']) && $item['id'] > 0) {
                        MenuApiFacade::updateById($item['id'], $item);
                    } else {
                        $item['menu_id'] = $menu_id;
                        $insertApiList[] = $item;
                    }
                }, $apiList);
                if (!empty($insertApiList)) {
                    MenuApiFacade::insertAll($insertApiList);
                }
            } else {
                //新增菜单
                $menu_id = $this->insertGetId($paramData);
                //新增Meta
                $metaData['menu_id'] = $menu_id;
                MenuMetaFacade::insertGetId($metaData);
                //新增Api
                $apiList = array_map(function ($item) use ($menu_id) {
                    $item['menu_id'] = $menu_id;
                    return $item;
                }, $apiList);
                MenuApiFacade::insertAll($apiList);
            }
        });
        return $paramData;
    }
}